package com.whfc.ms.api.mach.service.impl;

import com.whfc.common.enums.DelFlag;
import com.whfc.common.util.DateUtil;
import com.whfc.common.util.Gps;
import com.whfc.common.util.PositionUtil;
import com.whfc.fuum.dto.SysDeptDTO;
import com.whfc.fuum.service.SysDeptService;
import com.whfc.mach.dto.AppMachDataLogDTO;
import com.whfc.mach.dto.AppMachOilLogDTO;
import com.whfc.mach.dto.AppMachOilSheetDTO;
import com.whfc.mach.entity.AppDeviceObdLog;
import com.whfc.mach.entity.AppMachDataLog;
import com.whfc.mach.enums.WorkState;
import com.whfc.mach.service.AppMachConfigService;
import com.whfc.mach.service.AppMachDataService;
import com.whfc.mach.service.AppReportService;
import com.whfc.mach.service.ObdDataService;
import com.whfc.ms.api.mach.service.MsMachInnerService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * @author sun_guodong
 * @description
 * @date 2020-12-16
 */
@Service
public class MsMachInnerServiceImpl implements MsMachInnerService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @DubboReference(interfaceClass = AppMachDataService.class, version = "1.0.0")
    private AppMachDataService appMachDataService;

    @DubboReference(interfaceClass = AppMachConfigService.class, version = "1.0.0")
    private AppMachConfigService appMachConfigService;

    @DubboReference(interfaceClass = SysDeptService.class, version = "1.0.0")
    private SysDeptService sysDeptService;

    @DubboReference(interfaceClass = AppReportService.class, version = "1.0.0")
    private AppReportService reportService;

    @DubboReference(interfaceClass = ObdDataService.class, version = "1.0.0")
    private ObdDataService obdLogService;

    @Override
    public void statMachDayData(Integer machId, Date date) {
        appMachDataService.statMachDayData(machId, date);
    }

    @Override
    public void statMachDayData(Date date) {
        appMachDataService.statMachDayData(date);
    }

    @Override
    public void statObdMachDayData(Date date) {
        obdLogService.statMachDayData(date);
    }

    @Override
    public void buildMachData(Integer machId, Integer deviceId, Date date, Double effic) {

        Random random = new Random();

        long time2 = DateUtil.addDays(date, 1).getTime();
        // 7:50—8:20
        long startWorkTime1 = DateUtil.addMinutes(date, 470 + random.nextInt(30)).getTime();
        // 11:50—12:20
        long endWorkTime1 = DateUtil.addMinutes(date, 710 + random.nextInt(30)).getTime();
        // 13:50—14:20
        long startWorkTime2 = DateUtil.addMinutes(date, 830 + random.nextInt(30)).getTime();
        // 17:55—18:30
        long endWorkTime2 = DateUtil.addMinutes(date, 1075 + random.nextInt(35)).getTime();
        List<AppMachDataLog> logList = new ArrayList<>();
        Integer oilPos = 1000;
        while (true) {
            int diff = 180 + (random.nextInt(60));
            date = DateUtil.addSeconds(date, diff);
            long times = date.getTime();
            AppMachDataLog log = new AppMachDataLog();
            log.setMachId(machId);
            log.setDeviceId(deviceId);
            log.setTime(date);
            log.setDelFlag(DelFlag.UNDELETE.getValue());

            //上午未开始工作
            if (times < startWorkTime1) {
                log.setWorkState(4);

            }
            //上午工作时间
            if (times >= startWorkTime1 && times < endWorkTime1) {
                log.setWorkState(generateWorkState(effic));
                oilPos = oilPos - (1 + (random.nextInt(5)));
            }
            //中午休息
            if (times >= endWorkTime1 && times < startWorkTime2) {
                log.setWorkState(4);
            }
            //下午工作时间
            if (times >= startWorkTime2 && times < endWorkTime2) {
                log.setWorkState(generateWorkState(effic));
                oilPos = oilPos - (1 + (random.nextInt(5)));
            }
            //下午工作结束
            if (times >= endWorkTime2) {
                log.setWorkState(4);
            }

            //当天结束
            if (times > time2) {
                break;
            }

            if (oilPos < 20) {
                oilPos = 1000;
            }

            // 油位
            log.setOilPos(oilPos);

            // 轨迹坐标
            Gps gps = new Gps(30.482877, 114.413295);
            Gps randomLatLng = PositionUtil.getRandomLatLng(gps);
            log.setLat(randomLatLng.getLat());
            log.setLng(randomLatLng.getLng());
            log.setLocation("");
            logList.add(log);
        }

        appMachDataService.addMachDataLog(logList);

        appMachDataService.statMachDayData(machId, date);

    }

    @Override
    public void transferData(Integer srcMachId, Integer desMachId, Date srcDate, Date desDate, Double lngDiff, Double latDiff) {
        String srcDateStr = DateUtil.formatDate(srcDate);
        String desDateStr = DateUtil.formatDate(desDate);

        List<AppMachDataLogDTO> logDTOList = appMachDataService.getMachDataLogCache(srcMachId, srcDate);
        logger.info("logList:{}", logDTOList.size());
        if (logDTOList.size() > 0) {
            List<AppMachDataLog> logList = new ArrayList<>(logDTOList.size());
            for (int i = 0; i < logDTOList.size(); i++) {
                AppMachDataLogDTO logDTO = logDTOList.get(i);
                logger.info("i={},time:{}", i, logDTO.getTime());
                //
                String timeStr = DateUtil.formatDateTime(logDTO.getTime());
                Double lng = null;
                Double lat = null;
                if (PositionUtil.isInChina(logDTO.getLng(), logDTO.getLat())) {
                    lng = logDTO.getLng() + lngDiff;
                    lat = logDTO.getLat() + latDiff;
                }

                //String location = QQMapUtil.getLocation(lat, lng);
                AppMachDataLog log = new AppMachDataLog();
                BeanUtils.copyProperties(logDTO, log);
                log.setMachId(desMachId);
                log.setTime(DateUtil.parseDateTime(timeStr.replace(srcDateStr, desDateStr)));
                log.setLng(lng);
                log.setLat(lat);
                log.setDelFlag(DelFlag.UNDELETE.getValue());
                //log.setLocation(location);
                logList.add(log);
            }
            appMachDataService.addMachDataLog(logList);
        }
    }

    @Override
    public void statMachMonthData(Date date) {
        Date monthBegin = DateUtil.getMonthBegin(date);
        Date monthEnd = DateUtil.getMonthEnd(date);
        List<SysDeptDTO> deptList = sysDeptService.getAllProjectList();
        if (deptList.size() > 0) {
            for (SysDeptDTO sysDept : deptList) {
                try {
                    List<Integer> deptIds = sysDeptService.getDescendantDeptIdList(sysDept.getId());
                    if (deptIds == null || deptIds.size() == 0) {
                        continue;
                    }
                    reportService.statMachMonthData(deptIds, monthBegin, monthEnd);
                } catch (Exception e) {
                    logger.error("deptId:{},统计设备每月数据失败,{}", sysDept.getId(), e);
                    continue;
                }
            }
        }
    }

    @Override
    public void refreshPolygonWKT(Integer deptId) {
        appMachConfigService.refreshPolygonWKT(deptId);
    }

    @Override
    public void amendMachDeviceData(List<AppMachDataLog> param) {
        for (AppMachDataLog machDataLog : param) {
            machDataLog.setTime(DateUtil.addHours(machDataLog.getTime(), 8));
        }
        appMachDataService.amendDeviceData(param);
    }

    @Override
    public void amendObdDeviceData(AppDeviceObdLog param) {
        param.setTime(DateUtil.addHours(param.getTime(), 8));
        obdLogService.amendObdDeviceData(param);
    }

    @Override
    public List<AppMachOilLogDTO> getMachOilLog(Integer deviceId, Date startTime, Date endTime) {
        return appMachDataService.getDeviceOilLog(deviceId, startTime, endTime);
    }

    @Override
    public void saveMachOilSheet(Integer machId, List<AppMachOilSheetDTO> oilSheetDTOList) {
        appMachDataService.saveMachOilSheet(machId, oilSheetDTOList);
    }

    @Override
    public List<AppMachOilSheetDTO> getMachOilSheet(Integer machId) {
        return appMachDataService.getMachOilSheet(machId);
    }

    private Integer generateWorkState(Double effic) {
        if (effic == 0) {
            return WorkState.STOP.getValue();
        }
        Random random = new Random();
        int val = random.nextInt(100);
        // 工作
        if (val >= 0 && val <= effic) {
            return WorkState.RUN.getValue();
        } else {
            // 怠机
            return WorkState.IDLE.getValue();
        }
    }
}
